(def kdtree (points depth)
  "KD-Tree generation algorithm
   Args:
     points: (cons -> cons -> num)
       '((x1 y1) (x2 y2) (x3 y3))
     depth: (num)
   Returns:
     Tree: (split-point branch-a branch-b)"
  (when points
    (if (<= (len points) 2) ; So that it doesn't split the branch when
        points              ; it would end with nil elements.
        (let k (len:points 0)
          (with (axis (mod depth k)     ; Select split axis
                 middle (trunc:/ (len points) 2))
            (zap [sort (fn (x y) (< (x axis) (y axis))) _] points)
            (list (points middle)
                  (kdtree (firstn middle points) (+ 1 depth))
                  (kdtree (nthcdr (+ middle 1) points) (+ 1 depth))))))))